/* eslint-env browser */
<template>
  <div style="margin : 15px;">
<!--    <h3 style="margin-left:350px;font-weight: bold;">近一年汽车销量数据竞速条形图(辆)</h3>-->
    <div id="chart">
    </div>
  </div>
</template>

<script>

import * as d3 from "d3";
import "d3-selection-multi";
import datas from "../assets/data.json";


export default {
  name : "RaceChart",
  data(){
    return{
      datas
    }
  },
  methods : {
    renderChart : function() {

      const tickDuration = 800 //刻度持续时间
      const top_n = 10.5;//可显示最大数据量

      const height = 400;
      const width = 1000;

      const halo = function(text, strokeWidth) {
        text.select(function() { return this.parentNode.insertBefore(this.cloneNode(true), this); })
            .style({
              fill: '#ffffff',
              stroke: '#ffffff',
              'stroke-width': strokeWidth,
              'stroke-linejoin': 'round',
              opacity: 1
            });
      }

      const svg = d3.select("#chart").append("svg")
          .attr("width", width)
          .attr("height", height)
          .attr("class", "graph-svg-component");

      const margin = {
        top: 60,
        right: 30,
        bottom: 5,
        left: 200   //调节图表位置
      };

      let barPadding = (height-(margin.bottom+margin.top))/(top_n*5);
      let year = 2022.07;
      let TextYear;

      datas.forEach(d => {
        d.value = +d.value,
            d.lastValue = +d.lastValue,
            d.value = isNaN(d.value) ? 0 : d.value,
            d.year = +d.year,//+转化为数字，不行则返回Nan
            d.colour = d3.hsl(Math.random()*360,0.75,0.75)//随机取色
      });
      /*let xxx =[];
      xxx = datas.filter(d=>d.rank==1);//过滤
      console.log(xxx);
      ;*/
      console.log(datas[0].rank);
      console.log("Execution")
      let yearSlice = datas.filter(d => d.year == year && !isNaN(d.value))
          .sort((a,b) => b.value - a.value)
          .slice(0,top_n);

      console.log(yearSlice);

      yearSlice.forEach((d,i) => d.rank = i);

      let x = d3.scaleLinear()     //数据映射
          .domain([0, d3.max(yearSlice, d => d.value)])     //原始数据范围
          .range([margin.left-100, width-margin.right-50]);    //被映射到的数据烦诶

      let y = d3.scaleLinear()
          .domain([top_n, 0])
          .range([height-margin.bottom, margin.top]);

      let xAxis = d3.axisTop()
          .scale(x)
          .ticks(width > 500 ? 5:2)
          .tickSize(-(height-margin.top-margin.bottom))
          .tickFormat(d => d3.format(',')(d));
      svg.append('g')
          .attrs({
            class: 'axis xAxis',
            transform: `translate(0, ${margin.top})`
          })
          .call(xAxis)
          .selectAll('.tick line')
          .classed('origin', d => d == 0);

      svg.selectAll('rect.bar')//为所有条形框添加属性
          .data(yearSlice, d => d.name)
          .enter()
          .append('rect')
          .attrs({
            class: 'bar',
            x: x(0)+1,
            width: d => x(d.value)-x(0)-1,
            y: d => y(d.rank)+5,
            height: y(1)-y(0)-barPadding,
            rx:"5",//调整矩形圆角
            ry:"5"
          })
          .styles({
            fill: d => d.colour
          });

      svg.selectAll('text.label')
          .data(yearSlice, d => d.name)
          .enter()
          .append('text')
          .attrs({
            class: 'label',
            x: d => x(d.value)-8,
            y: d => y(d.rank)+5+((y(1)-y(0))/2)+1,
            'text-anchor': 'end'
          })
          .html(d => d.name);

      svg.selectAll('text.valueLabel')
          .data(yearSlice, d => d.name)
          .enter()
          .append('text')
          .attrs({
            class: 'valueLabel',
            x: d => x(d.value)+5,
            y: d => y(d.rank)+5+((y(1)-y(0))/2)+1,
          })
          .text(d => d3.format(',.0f')(d.lastValue));

      let yearText = svg.append('text')
          .attrs({
            class: 'yearText',
            x: width-margin.right,
            y: height-25
          })
          .styles({
            'text-anchor': 'end'  //右对齐
          })
          .call(halo, 10);

      let ticker = d3.interval(e => {

        yearSlice = datas.filter(d => d.year == year && !isNaN(d.value))
            .sort((a,b) => b.value - a.value)
            .slice(0,top_n);

        yearSlice.forEach((d,i) => d.rank = i);

        x.domain([0, d3.max(yearSlice, d => d.value)]);

        svg.select('.xAxis')
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .call(xAxis);

        let bars = svg.selectAll('.bar').data(yearSlice, d => d.name);

        bars
            .enter()        //在绑定数据之后，选择缺少的那部分DOM元素
            .append('rect')
            .attrs({
              class: d => `bar ${d.name.replace(/\s/g,'_')}`,
              x: x(0)+1,
              width: d => x(d.value)-x(0)-1,
              y: d => y(top_n+1)+5,
              height: y(1)-y(0)-barPadding,
              rx: 5,
              ry:5
            })
            .styles({
              fill: d => d.colour
            })
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              y: d => y(d.rank)+5
            });

        bars
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              width: d => x(d.value)-x(0)-1,
              y: d => y(d.rank)+5
            });

        bars
            .exit()
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              width: d => x(d.value)-x(0)-1,
              y: d => y(top_n+1)+5
            })
            .remove();

        let labels = svg.selectAll('.label').data(yearSlice, d => d.name);

        labels
            .enter()
            .append('text')
            .attrs({
              class: 'label',
              x: d => x(d.value)-8,
              y: d => y(top_n+1)+5+((y(1)-y(0))/2),
              'text-anchor': 'end'
            })
            .html(d => d.name)
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              y: d => y(d.rank)+5+((y(1)-y(0))/2)+1,
            });

        labels
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              x: d => x(d.value)-8,
              y: d => y(d.rank)+5+((y(1)-y(0))/2)+1
            });

        labels
            .exit()
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              x: d => x(d.value)-8,
              y: d => y(top_n+1)+5
            })
            .remove();

        let valueLabels = svg.selectAll('.valueLabel').data(yearSlice, d => d.name);

        valueLabels
            .enter()
            .append('text')
            .attrs({
              class: 'valueLabel',
              x: d => x(d.value)+5,
              y: d => y(top_n+1)+5,
            })
            .text(d => d3.format(',.0f')(d.lastValue))
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              y: d => y(d.rank)+5+((y(1)-y(0))/2)+1
            });

        valueLabels
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              x: d => x(d.value)+5,
              y: d => y(d.rank)+5+((y(1)-y(0))/2)+1
            })
            .tween("text", function(d) {
              let i = d3.interpolateRound(d.lastValue, d.value);
              return function(t) {
                this.textContent = d3.format(',')(i(t));
              };
            });

        valueLabels
            .exit()
            .transition()
            .duration(tickDuration)
            .ease(d3.easeLinear)
            .attrs({
              x: d => x(d.value)+5,
              y: d => y(top_n+1)+5
            })
            .remove();

        yearText.html(TextYear);// 显示对应年月

        if(year == 2023.05) ticker.stop();   //年份增加
        if((year*100)%100==12){
          year = d3.format('.2f')((+year) + 0.89); //year前加+，转化为number类型
          TextYear = (~~year)+"年"+((year*100)%100)+"月";
        }else{
          year = d3.format('.2f')((+year) + 0.01);
          TextYear = (~~year)+"年"+((year*100)%100)+"月";
        }
      },tickDuration);

      return svg.node();
    }
  },
  mounted : function(){
    this.renderChart();
  }
}

</script>

<style>
text{
  font-size: 20px;
  font-family: Open Sans, sans-serif;
}
text.title{
  font-size: 40px;
  font-weight: 500;
}
text.subTitle{
  font-weight: 500;
  fill: #777777;
}
text.caption{
  font-weight: 400;
  font-size: 14px;
  fill: #777777;
}
text.label{
  font-weight: 600;
}
text.yearText{
  font-size: 120px;
  font-weight: 700;
  opacity: 0.15;
}
.tick text {
  fill: #777777;
}
.xAxis .tick:nth-child(2) text {
  text-anchor: start;
}
.tick line {
  shape-rendering: CrispEdges;
  stroke: #949393;
}
.tick line.origin{
  stroke: #797272;
}
path.domain{
  display: none;
}
.graph-svg-component {
 margin: 0px;
}
</style>
